#include <iostream>
#include <string>
#include <map>
#include <chrono>
#include <thread>
#include <mqtt/async_client.h>

class MqttClientHandler
{
public:
    MqttClientHandler(const std::string& serverAddress, const std::string& clientId)
            : client_(serverAddress, clientId), connOpts_()
    {
        connOpts_.set_clean_session(true);
        client_.set_callback(cb_);
    }

    void connect()
    {
        try {
            std::cout << "Connecting to the MQTT server..." << std::endl;
            client_.connect(connOpts_)->wait();
            std::cout << "Connected to the server!" << std::endl;

            // 订阅公共响应主题
            client_.subscribe(RESPONSE_TOPIC, 1)->wait();
        }
        catch (const mqtt::exception& exc) {
            std::cerr << "Error connecting to the MQTT server: " << exc.what() << std::endl;
            throw;
        }
    }

    void disconnect()
    {
        try {
            std::cout << "Disconnecting from the MQTT server..." << std::endl;
            client_.disconnect()->wait();
            std::cout << "Disconnected!" << std::endl;
        }
        catch (const mqtt::exception& exc) {
            std::cerr << "Error disconnecting from the MQTT server: " << exc.what() << std::endl;
        }
    }

    void registerDevice(const std::string& deviceId)
    {
        response_map_[deviceId] = "";
    }

    void publishMessage(const std::string& deviceId)
    {
        try {
            std::string requestTopic = PUBLISH_TOPIC_BASE + deviceId;
            std::string payload = PAYLOAD + deviceId;

            std::cout << "Publishing message to " << deviceId << ": " << payload << std::endl;
            auto pubmsg = mqtt::make_message(requestTopic, payload);
            pubmsg->set_qos(1);
            client_.publish(pubmsg)->wait();

            // 等待设备响应
            std::this_thread::sleep_for(std::chrono::seconds(2));

            // 输出设备响应
            std::string response = response_map_[deviceId];
            std::cout << "Final response from " << deviceId << ": " << response << std::endl;
        }
        catch (const mqtt::exception& exc) {
            std::cerr << "Error publishing message to " << deviceId << ": " << exc.what() << std::endl;
        }
    }

private:
    mqtt::async_client client_;
    mqtt::connect_options connOpts_;
    std::map<std::string, std::string> response_map_;

    const std::string PUBLISH_TOPIC_BASE = "gateway/request/";
    const std::string RESPONSE_TOPIC = "gateway/response";
    const std::string PAYLOAD = "Requesting data from device ";

    // 自定义回调类
    class callback : public virtual mqtt::callback
    {
    public:
        callback(std::map<std::string, std::string>& response_map)
                : response_map_(response_map) {}

        void message_arrived(mqtt::const_message_ptr msg) override {
            std::string payload = msg->to_string();
            std::string device_id;
            std::string device_data;

            // 假设消息格式为 "device_id:data"
            auto separator_pos = payload.find(':');
            if (separator_pos != std::string::npos) {
                device_id = payload.substr(0, separator_pos);
                device_data = payload.substr(separator_pos + 1);

                // 存储设备响应
                response_map_[device_id] = device_data;

                std::cout << "Received message from device '" << device_id << "': " << device_data << std::endl;
            } else {
                std::cerr << "Malformed message received: " << payload << std::endl;
            }
        }

    private:
        std::map<std::string, std::string>& response_map_;
    } cb_{response_map_};  // 使用 response_map_ 构造回调对象
};

int main()
{
    // 创建MqttClientHandler对象
    MqttClientHandler mqttHandler("tcp://broker.emqx.io:1883", "sync_client");

    // 连接到MQTT服务器
    mqttHandler.connect();

    // 注册设备并发送请求
    std::vector<std::string> device_ids = {"device1", "device2", "device3"};
    for (const auto& device_id : device_ids) {
        mqttHandler.registerDevice(device_id);
        mqttHandler.publishMessage(device_id);
    }

    // 断开连接
    mqttHandler.disconnect();

    return 0;
}
